/*
 * @Author: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @Date: 2025-07-01 11:48:16
 * @LastEditors: 无聊 7989314+Hwz1997@user.noreply.gitee.com
 * @LastEditTime: 2025-10-24 10:31:45
 * @FilePath: \keep_motion_api\models\user\healthAssess.model.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// 健康评估模型
const healthAssessSchema = new Schema({
  user_id: { 
    type: Schema.Types.ObjectId, 
    ref: 'User',
    required: true 
  },
  // 身体质量指数
  // 计算方法：体重（kg）/ 身高（m）^ 2
  // 正常范围：18.5 - 24.9
  // 数越大，体重越重，越需要注意
  bmi: Number,
  // 心率
  heart_rate: Number,
  // 血压
  blood_pressure: String,
  // 肌肉质量
  muscle_mass: Number,
  // 评估日期
  assessment_date: { type: Date, default: Date.now },
  // 医疗历史
  medical_history: [String],
  // 推荐课程
  recommended_courses: [{
    type: Schema.Types.ObjectId,
    ref: 'Course'
  }],
  // 身高
  height: Number,
  // 体重
  weight: Number,
  // 体脂率
  body_fat_rate: Number,
  health_score: Number
});
healthAssessSchema.statics.getAssessments = async function (user_id, user_name, offset, limit) {
  try {
    const query = {};
    if (user_id) query.user_id = user_id;
    if (user_name) {
      const { User } = require('./');
      const parentQuery = {};
      const escapedUserName = escapeRegex(user_name);
      parentQuery.name = { $regex: escapedUserName, $options: 'i' };
      const users = await User.find(parentQuery).lean();
      if (users.length === 0) return { total: 0, rows: [] };
      query.user_id = { $in: users.map(user => user._id) };
    }
    // 先统计符合条件的记录总数
    const total = await this.countDocuments(query);
    // 再进行分页查询和关联数据获取
    const rows = await this.aggregate([
      // 匹配查询条件
      { $match: query },
      // 关联用户信息
      { $lookup: {
        from: 'users',
        localField: 'user_id',
        foreignField: '_id',
        as: 'user_info'
      }},
      // 关联推荐课程信息
      { $lookup: {
        from: 'courses',
        localField: 'recommended_courses',
        foreignField: '_id',
        as: 'courses_info'
      }},
      // 打平用户信息数组
      { $unwind: {
        path: '$user_info',
        preserveNullAndEmptyArrays: true
      }},
      // 投影需要的字段，将user_id的信息扁平化
      { $project: {
        _id: 1,
        user_id: 1,
        user_name: '$user_info.name',
        user_avatar: '$user_info.avatar',
        height: 1,
        weight: 1,
        body_fat_rate: 1,
        health_score: 1,
        bmi: 1,
        heart_rate: 1,
        blood_pressure: 1,
        muscle_mass: 1,
        assessment_date: 1,
        medical_history: 1,
        recommended_courses: {
          $map: {
            input: '$courses_info',
            as: 'course',
            in: {
              _id: '$$course._id',
              title: '$$course.title',
              description: '$$course.description'
            }
          }
        }
      }},
      // 排序
      { $sort: { assessment_date: -1 } },
      // 分页
      { $skip: Number(offset) },
      { $limit: Number(limit) }
    ]);
    return { rows, total };
  } catch (error) {
    throw error;
  } 
}
healthAssessSchema.statics.createAssessment = async function (assessmentData) {
  try {
    // 计算相关参数
    const newAssessmentData = calculateParams(assessmentData);
    // 相关课程
    // 根据健康评分推荐课程
    newAssessmentData.recommended_courses = recommendCourses(newAssessmentData);
    const assessment = new this(newAssessmentData);
    return await assessment.save();
  } catch (error) {
    throw error;
  }
}
healthAssessSchema.statics.updateAssessment = async function (id, assessmentData) {
  try {
    assessmentData.updated_at = Date.now();
    // 计算相关参数
    const newAssessmentData = calculateParams(assessmentData);
    return await this.findByIdAndUpdate(id, newAssessmentData, { new: true });
  } catch (error) {
    throw error;
  }
}
healthAssessSchema.statics.getStats = async function (user_id) {
  try {
    let query = {};
    if (user_id) query = {$expr: {$eq: [{ $toString: "$user_id" }, user_id.toString()]}};
    const pipeline = [
      { $match: query },
      { $sort: { assessment_date: -1 } },
      { $group: {
          _id: "$user_id",
          latest_assessment: { $first: "$$ROOT" },
          assessments_count: { $sum: 1 },
          avg_bmi: { $avg: '$bmi' },
          avg_heart_rate: { $avg: '$heart_rate' },
          avg_muscle_mass: { $avg: '$muscle_mass' }
      }},
      { $project: {
        _id: 1,
        latest_assessment: 1,
        assessments_count: 1,
        avg_bmi: { $round: ['$avg_bmi', 2] },
        avg_heart_rate: { $round: ['$avg_heart_rate', 2] },
        avg_muscle_mass: { $round: ['$avg_muscle_mass', 2] }
      }}
    ];
    const result = await this.aggregate(pipeline);
    return result.length > 0 ? result[0] : null;
  } catch (error) {
    throw error;
  }
}

// 计算相关参数
function calculateParams(assessmentData) {
  if(!assessmentData.height || !assessmentData.weight) throw new Error('身高和体重不能为空');
  // 计算身体质量指数
  assessmentData.bmi = parseFloat((assessmentData.weight / (assessmentData.height * assessmentData.height)).toFixed(2));
  // 计算体脂率
  assessmentData.body_fat_rate = parseFloat((assessmentData.weight - assessmentData.muscle_mass) / assessmentData.weight * 100).toFixed(2);
  // 计算健康评分
  assessmentData.health_score = parseFloat((assessmentData.bmi - 18.5) / (24.9 - 18.5) * 30 + (1 - assessmentData.body_fat_rate / 100) * 30).toFixed(2);
  return assessmentData;
}

// 推荐课程
function recommendCourses(assessmentData) {
  if (assessmentData.health_score < 30) {
    return ['68cb5625e523fa2828c2ed74'];
  } else if (assessmentData.health_score < 60) {
    return ['68cb5625e523fa2828c2ed74', '68cb5625e523fa2828c2ed74'];
  } else {
    return ['68cb5625e523fa2828c2ed74', '68cb5625e523fa2828c2ed74', '68cb5625e523fa2828c2ed74'];
  }
}

module.exports = mongoose.model('HealthAssess', healthAssessSchema);
